package com.cloudcc.ccTool;

import org.reflections.Reflections;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;

public class TriggerInvoker {
    public UserInfo uinfo = null;
    String operate = "";
    String triggerTime = "";
    public TriggerInvoker (UserInfo userInfo,String operate,String triggerTime){
        this.uinfo = userInfo;
        this.operate = operate;
        this.triggerTime = triggerTime;
    }
    public TriggerInvoker(){

    }
    public ServiceResult handler(CCObject data) throws Exception{
        String objectApiName = data.getObjectApiName();
        ServiceResult sr = new ServiceResult();
        Reflections ref = new Reflections("com.cloudcc.trigger");
        Set<Class<? extends CCTrigger>> clsSets = ref.getSubTypesOf(CCTrigger.class);
        for (Class<? extends CCTrigger> subCls : clsSets){
            try {
                Constructor cons = subCls.getConstructor(CCObject.class,CCObject.class,ServiceResult.class,UserInfo.class);
                CCTrigger trigger = (CCTrigger) cons.newInstance(data,null,sr,uinfo);
                String objectApiNameTmp = (String) trigger.getObjectApiName();
                if (objectApiName != null && objectApiName.equals(objectApiNameTmp)) {
                    if ("before".equals(triggerTime) && "insert".equals(operate)) {
                        trigger.do_insert_before();
                    }
                    if ("after".equals(triggerTime) && "insert".equals(operate)) {
                        String id = (String)data.get("id");
                        trigger.setRecordOldVal(id);
                        trigger.do_insert_after();
                    }
                    if ("before".equals(triggerTime) && "update".equals(operate)) {
                        String id = (String)data.get("id");
                        trigger.setRecordOldVal(id);
                        trigger.do_update_before();
                    }
                    if ("after".equals(triggerTime) && "update".equals(operate)) {
                        String id = (String)data.get("id");
                        trigger.setRecordOldVal(id);
                        trigger.do_update_after();
                    }
                    if ("before".equals(triggerTime) && ("upsert".equals(operate) || "insert".equals(operate) || "update".equals(operate))) {
                        trigger.do_upsert_before();
                    }
                    if ("after".equals(triggerTime) && ("upsert".equals(operate) || "insert".equals(operate) || "update".equals(operate))) {
                        String id = (String)data.get("id");
                        trigger.setRecordOldVal(id);
                        trigger.do_upsert_after();
                    }
                    if ("before".equals(triggerTime) && "delete".equals(operate)) {
                        String id = (String)data.get("id");
                        trigger.setRecordOldVal(id);
                        trigger.do_delete_before();
                    }
                    if ("after".equals(triggerTime) && "delete".equals(operate)) {
                        String id = (String)data.get("id");
                        trigger.setRecordOldVal(id);
                        trigger.do_delete_after();
                    }
                    if ("approval".equals(operate)) {
                        trigger.do_approval();
                    }
                }
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }catch (Exception ex) {
                throw ex;
            }
        }
        return sr;
    }
}
